package com.yanqu.road.dao.impl.cross.cookboy;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.db.DbParameter;
import com.yanqu.road.dao.impl.TempDao;
import com.yanqu.road.entity.activity.cookboy.CookBoyMatch;
import com.yanqu.road.entity.activity.cookboy.process2.CookBoy2DishTable;
import com.yanqu.road.entity.activity.cookboy.process2.CookBoyUpUser;
import com.yanqu.road.entity.activity.cookboy.process2.CookBoy2UserJoinData;
import com.yanqu.road.entity.activity.cookboy.process3.CookBoy3Table;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossCookBoyDaoImpl extends TempDao {


    public boolean addCrossCookBoy3TableList(List<CookBoy3Table> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCrossDb());
        String sql = "INSERT INTO t_c_activity_cookboy3_table(activityId,userId,no,openItemId,serverId,joinerData,integral,openTime,overTime) VALUES(?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoy3Table info : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, info.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getNo()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getOpenItemId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getServerId()));
            para.put(i++, new DbParameter(Types.VARCHAR, info.getJoinerData()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getOpenTime()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getOverTime()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateCrossCookBoy3TableList(List<CookBoy3Table> list) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_cookboy3_table SET joinerData=?,overTime=?,integral=?" +
                " WHERE activityId=? and userId = ? AND no=?";
        getDb().setConnName(DbNameStrategy.getCrossDb());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoy3Table data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.VARCHAR, data.getJoinerData()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOverTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getIntegral()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getNo()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public Map<Long,Map<Integer, CookBoy3Table>> getCrossCookBoy3TableMap(int activityId) {
        Map<Long,Map<Integer, CookBoy3Table>> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_cookboy3_table WHERE activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCrossDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoy3Table data = initCrossCookBoy3Table(rs);
                if(!dataMap.containsKey(data.getUserId())){
                    dataMap.put(data.getUserId(),new ConcurrentHashMap<>());
                }
                dataMap.get(data.getUserId()).put(data.getNo(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    //跨服的玩家坑位信息
    private CookBoy3Table initCrossCookBoy3Table(ResultSet rs) throws SQLException {
        CookBoy3Table data = new CookBoy3Table();
        data.setActivityId(rs.getInt("activityId"));
        data.setServerId(rs.getLong("serverId"));
        data.setUserId(rs.getLong("userId"));
        data.setOpenItemId(rs.getInt("openItemId"));
        data.setNo(rs.getInt("no"));
        data.setIntegral(rs.getLong("integral"));
        data.setOpenTime(rs.getLong("openTime"));
        data.setOverTime(rs.getLong("overTime"));
        data.setJoinerData(rs.getString("joinerData"));
        return data;
    }


    public boolean updateJoinRelationList(List<CookBoy2UserJoinData> list) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_cookboy_relation SET joinTimes1=?,joinTimes2=?,lastJoinTime=?,otherActivityId=?" +
                " WHERE activityId=? and userId1 = ? and userId2 = ?";
        getDb().setConnName(DbNameStrategy.getCrossDb());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoy2UserJoinData data : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, data.getJoinTime1()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getJoinTime2()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getLastJoinTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getOtherActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId1()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId2()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean addJoinRelationList(List<CookBoy2UserJoinData> list) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCrossDb());
        String sql = "INSERT INTO t_c_activity_cookboy_relation(userId1,joinTimes1,userId2,joinTimes2,activityId,lastJoinTime,otherActivityId) VALUES(?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoy2UserJoinData info : list) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.BIGINT, info.getUserId1()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getJoinTime1()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getUserId2()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getJoinTime2()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getLastJoinTime()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getOtherActivityId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public List<CookBoy2UserJoinData> getCookBoy2UserJoinData(int activityId) {
        List<CookBoy2UserJoinData> list = new ArrayList<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_cookboy_relation WHERE activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCrossDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoy2UserJoinData data = initCookBoy2UserJoinData(rs);
                list.add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return list;
    }

    private CookBoy2UserJoinData initCookBoy2UserJoinData(ResultSet rs) throws SQLException {
        CookBoy2UserJoinData data = new CookBoy2UserJoinData();
        data.setActivityId(rs.getInt("activityId"));
        data.setOtherActivityId(rs.getInt("otherActivityId"));
        data.setUserId1(rs.getLong("userId1"));
        data.setUserId2(rs.getLong("userId2"));
        data.setJoinTime1(rs.getInt("joinTimes1"));
        data.setJoinTime2(rs.getInt("joinTimes2"));
        data.setLastJoinTime(rs.getLong("lastJoinTime"));
        return data;
    }

    public Map<Long, CookBoyUpUser> getCrossCookBoy2UserMap(int activityId) {
        Map<Long, CookBoyUpUser> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_cookboy_user WHERE activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCrossDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoyUpUser data = initCrossCookBoy2User(rs);
                dataMap.put(data.getUserId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    private CookBoyUpUser initCrossCookBoy2User(ResultSet rs) throws SQLException {
        CookBoyUpUser data = new CookBoyUpUser();
        data.setActivityId(rs.getInt("activityId"));
        data.setServerId(rs.getLong("serverId"));
        data.setUserId(rs.getLong("userId"));
        data.setPos(rs.getInt("pos"));
        data.setType(rs.getInt("type"));
        data.setLastScore(rs.getLong("lastScore"));

        String forbiddenSpoon = rs.getString("forbiddenSpoon");
        data.setForbiddenSpoonList(StringUtils.isNullOrEmpty(forbiddenSpoon) ? new ArrayList<>() : JSON.parseObject(forbiddenSpoon, new TypeReference<List<Integer>>() {
        }));

        return data;
    }


    public boolean addCrossCookBoyUserList(List<CookBoyUpUser> cookBoy2UserList) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCrossDb());
        String sql = "INSERT INTO t_c_activity_cookboy_user(activityId,userId,serverId,pos,type,lastScore,forbiddenSpoon) VALUES(?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoyUpUser info : cookBoy2UserList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, info.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getUserId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getServerId()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getPos()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getType()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getLastScore()));
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(info.getForbiddenSpoonList())));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateCrossCookBoyUserList(List<CookBoyUpUser> cookBoy2UserList) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_cookboy_user SET forbiddenSpoon=?" +
                " WHERE activityId=? and userId = ?";
        getDb().setConnName(DbNameStrategy.getCrossDb());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoyUpUser data : cookBoy2UserList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getForbiddenSpoonList())));
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean addCrossDishTableList(List<CookBoy2DishTable> cookBoy2DishTableList) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCrossDb());
        String sql = "INSERT INTO t_c_activity_cookboy2_table(activityId,userId,no,userDishId,dishId,serverId,joinerData,integral,openTime,overTime) VALUES(?,?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoy2DishTable info : cookBoy2DishTableList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, info.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getNo()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getUserDishId()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getDishId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getServerId()));
            para.put(i++, new DbParameter(Types.VARCHAR, info.getJoinerData()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getOpenTime()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getOverTime()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateCrossDishTableList(List<CookBoy2DishTable> cookBoy2DishTableList) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_cookboy2_table SET joinerData=?,overTime=?,integral=?" +
                " WHERE activityId=? and userId = ? AND no=?";
        getDb().setConnName(DbNameStrategy.getCrossDb());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoy2DishTable data : cookBoy2DishTableList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.VARCHAR, data.getJoinerData()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOverTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getIntegral()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getNo()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateCrossMatchList(List<CookBoyMatch> cookBoyMatchList) {
        boolean result = false;
        String sql = "UPDATE t_c_activity_cookboy_table SET tableData=?,openTime=?,overTime=?" +
                " WHERE activityId=? and no=?";
        getDb().setConnName(DbNameStrategy.getCrossDb());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoyMatch data : cookBoyMatchList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.VARCHAR, data.getTableData()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOpenTime()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getOverTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getNo()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public Map<Integer, CookBoyMatch> getCrossMatchTableMap(int activityId) {
        Map<Integer, CookBoyMatch> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_cookboy_table WHERE activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCrossDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoyMatch data = initCrossMatchTable(rs);
                dataMap.put(data.getNo(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    public Map<Long,Map<Integer, CookBoy2DishTable>> getCrossDishTableMap(int activityId) {
        Map<Long,Map<Integer, CookBoy2DishTable>> dataMap = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT * FROM t_c_activity_cookboy2_table WHERE activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getCrossDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoy2DishTable data = initCrossDishTable(rs);
                if(!dataMap.containsKey(data.getUserId())){
                    dataMap.put(data.getUserId(),new ConcurrentHashMap<>());
                }
                dataMap.get(data.getUserId()).put(data.getNo(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    //跨服的玩家坑位信息
    private CookBoy2DishTable initCrossDishTable(ResultSet rs) throws SQLException {
        CookBoy2DishTable data = new CookBoy2DishTable();
        data.setActivityId(rs.getInt("activityId"));
        data.setServerId(rs.getLong("serverId"));
        data.setUserId(rs.getLong("userId"));
        data.setDishId(rs.getInt("dishId"));
        data.setUserDishId(rs.getInt("userDishId"));
        data.setNo(rs.getInt("no"));
        data.setIntegral(rs.getLong("integral"));
        data.setOpenTime(rs.getLong("openTime"));
        data.setOverTime(rs.getLong("overTime"));
        data.setJoinerData(rs.getString("joinerData"));
        return data;
    }

    //跨服的玩家坑位信息
    private CookBoyMatch initCrossMatchTable(ResultSet rs) throws SQLException {
        CookBoyMatch data = new CookBoyMatch();
        data.setActivityId(rs.getInt("activityId"));
        data.setNo(rs.getInt("no"));
        data.setTableData(rs.getString("tableData"));
        data.rankInit();
        data.setOpenTime(rs.getLong("openTime"));
        data.setOverTime(rs.getLong("overTime"));
        return data;
    }

    public boolean addCrossMatchTableList(List<CookBoyMatch> cookBoyMatchList) {
        boolean result = false;
        getDb().setConnName(DbNameStrategy.getCrossDb());
        String sql = "INSERT INTO t_c_activity_cookboy_table(activityId,no,tableData,openTime,overTime) VALUES(?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoyMatch info : cookBoyMatchList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, info.getActivityId()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getNo()));
            para.put(i++, new DbParameter(Types.VARCHAR, info.getTableData()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getOpenTime()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getOverTime()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

}
